﻿using System;
using System.Data.Entity;
using System.Security.Principal;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security;
using System.Web.SessionState;
using Ninject;
using WeBlog.Controllers;
using WeBlog.DataContext;
using WeBlog.Repositories;
using WeBlog.Services;

namespace WeBlog
{
    public class MvcApplication : System.Web.HttpApplication
    {
        public override void Init()
        {
            this.AuthenticateRequest += new System.EventHandler(MvcApplication_AuthenticateRequest);
            this.AcquireRequestState += new EventHandler(MvcApplication_AcquireRequestState);
        }

        void MvcApplication_AcquireRequestState(object sender, EventArgs e)
        {                     
            HttpSessionState session = HttpContext.Current.Session;
            if (session == null) return;

            if (session["User"] == null)
            {
                if (HttpContext.Current.User != null)
                {                    
                    if (!SiteManager.IsCurrentSiteConfigured()) return;
                    var kernel = new StandardKernel();
                    var unitOfWork = kernel.Get<WeBlogContext>();

                    var repo = new UserRepository(unitOfWork);
                    var user = repo.FindByEmail(HttpContext.Current.User.Identity.Name);
                    if (user != null)
                        session["User"] = user;
                }
            }
        }

        void MvcApplication_AuthenticateRequest(object sender, System.EventArgs e)
        {
            if (HttpContext.Current.User != null)
            {
                if (HttpContext.Current.User.Identity.IsAuthenticated)
                {
                    var cookie = Request.Cookies.Get(FormsAuthentication.FormsCookieName);
                    if (cookie != null)
                    {
                        var ticket = FormsAuthentication.Decrypt(cookie.Value);
                        // get the user & the roles that this user is in using your own logic
                        var identity = new GenericIdentity(ticket.Name);
                        var roles = ticket.UserData.Split(',');
                        var principal = new GenericPrincipal(identity, roles);
                        HttpContext.Current.User = principal;
                    }
                }
            }            
        }

        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            routes.IgnoreRoute("Services/MetaWeblogAPI.ashx");

            routes.MapRoute("ViewImages",
                "Images/{id}",
                new { controller = "Home", action = "GetImage", id = UrlParameter.Optional });                        

            routes.MapRoute("ViewFiles",
                "Files/{id}",
                new { controller = "Home", action = "GetFile", id = UrlParameter.Optional });

            routes.MapRoute("ViewCategory",
                "Categories/{name}",
                new { controller = "Category", action = "Details", id = UrlParameter.Optional });

            routes.MapRoute("ViewPost",
                "Posts/{slug}",
                new { controller = "Post", action = "Details", id = UrlParameter.Optional });

            routes.MapRoute("ViewPage",
                "Pages/{slug}",
                new { controller = "Page", action = "Details", id = UrlParameter.Optional });

            routes.MapRoute("ViewTag",
                "Tags/{name}",
                new { controller = "Tag", action = "Details", id = UrlParameter.Optional });

            routes.MapRoute("Default",
                "{controller}/{action}/{id}",
                new { controller = "Post", action = "Index", id = UrlParameter.Optional }
            );          
        }

        public static Func<ControllerContext, string> ThemeSelector
        {
            get
            {
                Func<ControllerContext, string> routeFunc = x => x.RouteData.Values.ContainsKey("Theme") ? x.RouteData.Values["Theme"].ToString() : null;
                Func<ControllerContext,string> siteFunc = x => SiteManager.IsCurrentSiteConfigured() ? SiteManager.CurrentConfiguration.Theme : "Default";
                return x => routeFunc.Invoke(x) ?? siteFunc.Invoke(x);
            }
        }
        
        public static void RegisterViewEngine(ViewEngineCollection viewEngines)
        {
            // We do not need the default view engine
            ControllerBuilder.Current.SetControllerFactory(new WeBlogControllerFactory());
            viewEngines.Clear();

            var themeableRazorViewEngine = new ThemeableRazorViewEngine(ThemeSelector);

            viewEngines.Add(themeableRazorViewEngine);
        }

        protected void Application_Start()
        {
            Database.DefaultConnectionFactory = new WeBlogConnectionFactory();
            Database.SetInitializer(new WeBlogDbInitializer());

            AreaRegistration.RegisterAllAreas();
            RegisterRoutes(RouteTable.Routes);
            RegisterViewEngine(ViewEngines.Engines); 
        }                         
    }
}